﻿using Cirrious.CrossCore;
using Cirrious.MvvmCross.ViewModels;
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace XXX.UI.WinRT
{
	/// <summary>
	/// Provides application-specific behavior to supplement the default Application class.
	/// </summary>
	sealed partial class App : Application
	{
		#region RegisterTypes

		public static void RegisterTypes()
		{
			// Framework
			var authorizationProvider = new Sidvall.Security.PublicAuthorizationProvider();
			Sidvall.SystemContext.Current = new Sidvall.SystemContext()
			{
				AuthorizationManager = new Sidvall.Security.AuthorizationManager(authorizationProvider),
				//AuthenticationManager = new Sidvall.Security.AuthenticationManager(new Sidvall.Security.AuthenticationProvider()),
				//CacheManager = new Sidvall.Caching.CacheManager(new Sidvall.Caching.MemoryCache()),
				//ClaimManager = new Sidvall.Security.ClaimManager(new Sidvall.Security.ClaimsPrincipalManager()),
				CodeManager = new Sidvall.Reflection.CodeManager(null),
				ExceptionManager = new Sidvall.ExceptionHandling.ExceptionManager(new Sidvall.ExceptionHandling.ExceptionProvider()),
				HttpClientFactory = new Sidvall.Net.HttpClientFactory(),
				//LogManager = new Sidvall.Logging.LogManager(new Sidvall.Logging.EL.Log()),
				//SmtpClientManager = new Sidvall.Net.Mail.SmtpClientManager(new Sidvall.Net.Mail.SmtpClient()),
				//SmsClientManager = new Sidvall.Net.Sms.SmsClientManager(new Sidvall.Net.Sms.SmsClient("")),
				SoapClientFactory = new Sidvall.Net.SoapClientFactory(),
				//SystemStorageManager = new Sidvall.IO.StorageManager(new Sidvall.IO.FileSystem()),
				//TransactionScopeFactory = new Sidvall.Data.TransactionScopeFactory(),
				TypeCache = new Sidvall.Reflection.TypeCache(),
				UserManager = new Sidvall.Security.UserManager(authorizationProvider),
				//UserStorageManager = new Sidvall.IO.StorageManager(new Sidvall.IO.Storage.LocalStorage()),

				// Client
				PrincipalContextManager = new Sidvall.Security.PrincipalContextManager(new Sidvall.Security.PrincipalContextProvider()),
				//PrincipalManager = new Sidvall.Security.PrincipalManager(new Sidvall.Security.PrincipalProvider()),

				// Server
				//PrincipalContextManager = new Sidvall.Security.PrincipalContextManager(new Sidvall.Web.Security.PrincipalContextProvider()),
				//PrincipalManager = new Sidvall.Security.PrincipalManager(new Sidvall.Web.Security.PrincipalProvider()),

				// Host specific
				//ResourceManager = new Sidvall.Resources.ResourceManager(new XXX.UI.Wpf.Resources.ResourceManager()),
				//SettingsManager = new Sidvall.Configuration.SettingsManager(new XXX.UI.Wpf.Configuration.ApplicationSettings()),
			};
			//Sidvall.Office.SystemContext.Current = new Sidvall.Office.SystemContext()
			//{
			//	ExcelManager = new Sidvall.Office.ExcelManager(new Sidvall.Office.Excel()),
			//};
			//Sidvall.SystemEnvironment.SystemContext.Current = new Sidvall.SystemEnvironment.SystemContext()
			//{
			//	Launcher = new Sidvall.SystemEnvironment.Windows.Launcher(),
			//};
			Sidvall.UI.SystemContext.Current = new Sidvall.UI.SystemContext()
			{
				ApplicationManager = new Sidvall.UI.ApplicationManager(),
				ConfigurationContext = new Sidvall.UI.Configuration.ConfigurationContext(new Sidvall.UI.WinRT.Views.ContentControlRegionManager()),
				//DialogManager = new Sidvall.UI.Dialogs.DialogManager(
				//	new Sidvall.UI.Wpf.Dialogs.FileDialog(),
				//	new Sidvall.UI.Wpf.Dialogs.FolderDialog(),
				//	new Sidvall.UI.Wpf.Dialogs.MessageDialogManager(),
				//	new Sidvall.UI.Wpf.Dialogs.SecurityDialogManager(),
				//	new Sidvall.UI.Wpf.Dialogs.ProgressDialogManager()),
				//InputManager = new Sidvall.UI.Wpf.Input.InputManager(),
				NavigationManager = new Sidvall.UI.Navigation.NavigationManager(),
			};

			// Application specific
			//XXX.SystemContext.Current.DataPortalStrategy = new Sidvall.DataPortal.DataPortalStrategy()
			//{
			//	MasterServerConnection = Sidvall.DataPortal.ServerConnectionManager.GetWebServiceConnection(Properties.Settings.Default.ServerRemoteAddress,
			//		XXX.SystemContext.Current.AuthenticationStrategy),
			//};
			// Server
			//Sidvall.Services.ServiceManager.Current.ServiceProvider = new Sidvall.Web.Services.ServiceProvider();
		}

		#endregion
		#region OnLaunched

		/// <summary>
		/// Invoked when the application is launched normally by the end user.  Other entry points
		/// will be used such as when the application is launched to open a specific file.
		/// </summary>
		/// <param name="e">Details about the launch request and process.</param>
		protected override void OnLaunched(LaunchActivatedEventArgs e)
		{

#if DEBUG
			if (System.Diagnostics.Debugger.IsAttached)
			{
				this.DebugSettings.EnableFrameRateCounter = true;
			}
#endif

			Frame rootFrame = Window.Current.Content as Frame;

			// Do not repeat app initialization when the Window already has content,
			// just ensure that the window is active
			if (rootFrame == null)
			{
				// Create a Frame to act as the navigation context and navigate to the first page
				rootFrame = new Frame();
				// Set the default language
				rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];

				rootFrame.NavigationFailed += OnNavigationFailed;

				if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
				{
					//TODO: Load state from previously suspended application
				}

				// Place the frame in the current Window
				Window.Current.Content = rootFrame;
			}

			if (rootFrame.Content == null)
			{
				// When the navigation stack isn't restored navigate to the first page,
				// configuring the new page by passing required information as a navigation
				// parameter
				rootFrame.Navigate(typeof(MainPage), e.Arguments);
				RegisterTypes();
				Sidvall.UI.WinRT.SystemContext.Current.MainWindow = rootFrame;
				var setup = new Setup(rootFrame);
				setup.Initialize();

				var start = Mvx.Resolve<IMvxAppStart>();
				start.Start();
			}
			// Ensure the current window is active
			Window.Current.Activate();
		}

		#endregion
		#region OnNavigationFailed

		/// <summary>
		/// Invoked when Navigation to a certain page fails
		/// </summary>
		/// <param name="sender">The Frame which failed navigation</param>
		/// <param name="e">Details about the navigation failure</param>
		void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
		{
			throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
		}

		#endregion
		#region OnSuspending

		/// <summary>
		/// Invoked when application execution is being suspended.  Application state is saved
		/// without knowing whether the application will be terminated or resumed with the contents
		/// of memory still intact.
		/// </summary>
		/// <param name="sender">The source of the suspend request.</param>
		/// <param name="e">Details about the suspend request.</param>
		private void OnSuspending(object sender, SuspendingEventArgs e)
		{
			var deferral = e.SuspendingOperation.GetDeferral();
			//TODO: Save application state and stop any background activity
			deferral.Complete();
		}

		#endregion
		#region Constructors

		/// <summary>
		/// Initializes the singleton application object.  This is the first line of authored code
		/// executed, and as such is the logical equivalent of main() or WinMain().
		/// </summary>
		public App()
		{
			this.InitializeComponent();
			this.Suspending += OnSuspending;
		}

		#endregion
	}
}
